package com.sky.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sky.constant.MessageConstant;
import com.sky.constant.StatusConstant;
import com.sky.context.BaseContext;
import com.sky.dto.SetmealDTO;
import com.sky.dto.SetmealPageQueryDTO;
import com.sky.entity.Setmeal;
import com.sky.entity.SetmealDish;
import com.sky.exception.BaseException;
import com.sky.exception.DeletionNotAllowedException;
import com.sky.mapper.SetmealDishMapper;
import com.sky.mapper.SetmealMapper;
import com.sky.result.PageResult;
import com.sky.service.SetmealService;
import com.sky.vo.DishItemVO;
import com.sky.vo.SetmealVO;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 套餐实现类
 *
 * @Author mr.lcc
 * @Data 2025/5/21 15:41
 */
@Service
public class SetmealServiceImpl extends ServiceImpl<SetmealMapper, Setmeal> implements SetmealService {

    @Autowired
    private SetmealMapper setmealMapper;

    @Autowired
    private SetmealDishMapper setmealDishMapper;

    /**
     * 新增套餐
     *
     * @param dto
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveSetmeal(SetmealDTO dto) {
        // 1.存套餐基本信息到setmeal表中
        Setmeal newSetmeal = new Setmeal();
        BeanUtils.copyProperties(dto, newSetmeal);
        this.save(newSetmeal);

        // 2.把套餐菜品关系存到setmeal_dish表中
        List<SetmealDish> setmealDishes = dto.getSetmealDishes();
        if (CollUtil.isNotEmpty(setmealDishes)) {
            List<SetmealDish> collect = setmealDishes.stream().map(sd -> {
                SetmealDish setmealDish = new SetmealDish();
                BeanUtils.copyProperties(sd, setmealDish);
                setmealDish.setSetmealId(newSetmeal.getId());
                return setmealDish;
            }).collect(Collectors.toList());
            // 3.批量插入
            setmealDishMapper.insertBatch(collect);
        }
    }

    /**
     * 套餐分页查询
     *
     * @param dto
     * @return
     */
    @Override
    public PageResult pageList(SetmealPageQueryDTO dto) {
        // 1.校验参数
        if (ObjectUtils.isEmpty(dto)) {
            throw new BaseException("分页参数为空");
        }

        // 2.分页查询
        Page<Setmeal> page = new Page<>(dto.getPage(), dto.getPageSize());
        this.lambdaQuery().eq(dto.getCategoryId() != null, Setmeal::getCategoryId, dto.getCategoryId()).eq(dto.getStatus() != null, Setmeal::getStatus, dto.getStatus()).like(ObjectUtils.isNotEmpty(dto.getName()), Setmeal::getName, dto.getName()).orderByDesc(Setmeal::getUpdateTime).page(page);

        return new PageResult(page.getTotal(), page.getRecords());
    }

    /**
     * 批量删除套餐
     *
     * @param ids
     */
    @Transactional
    @Override
    public void deleteBatch(List<Long> ids) {
        ids.forEach(id -> {
            Setmeal setmeal = setmealMapper.selectById(id);
            if (StatusConstant.ENABLE.equals(setmeal.getStatus())) {
                //起售中的套餐不能删除
                throw new DeletionNotAllowedException(MessageConstant.SETMEAL_ON_SALE);
            }
        });

        ids.forEach(setmealId -> {
            //删除套餐表中的数据
            setmealMapper.deleteById(setmealId);
            //删除套餐菜品关系表中的数据
            setmealDishMapper.deleteById(setmealId);
        });
    }

    /**
     * 根据id查询套餐和套餐菜品关系
     *
     * @param id
     * @return
     */
    @Override
    public SetmealVO getByIdWithDish(Long id) {
        Setmeal setmeal = setmealMapper.selectById(id);
        LambdaQueryWrapper<SetmealDish> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SetmealDish::getSetmealId, id);
        List<SetmealDish> setmealDishes = setmealDishMapper.selectList(queryWrapper);

        SetmealVO setmealVO = new SetmealVO();
        BeanUtils.copyProperties(setmeal, setmealVO);
        setmealVO.setSetmealDishes(setmealDishes);
        return setmealVO;
    }

    /**
     * 修改套餐
     *
     * @param setmealDTO
     */
    @Transactional
    @Override
    public void update(SetmealDTO setmealDTO) {
        Setmeal setmeal = new Setmeal();
        BeanUtils.copyProperties(setmealDTO, setmeal);
        setmeal.setUpdateTime(LocalDateTime.now());
        setmeal.setUpdateUser(BaseContext.getCurrentId());

        //1、修改套餐表，执行update
        setmealMapper.updateById(setmeal);

        //套餐id
        Long setmealId = setmealDTO.getId();

        //2、删除套餐和菜品的关联关系，操作setmeal_dish表，执行delete
        setmealDishMapper.deleteById(setmealId);

        List<SetmealDish> setmealDishes = setmealDTO.getSetmealDishes();
        setmealDishes.forEach(setmealDish -> {
            setmealDish.setSetmealId(setmealId);
        });
        //3、重新插入套餐和菜品的关联关系，操作setmeal_dish表，执行insert
        setmealDishMapper.insertBatch(setmealDishes);
    }

    /**
     * 套餐起售、停售
     *
     * @param status
     * @param id
     */
    @Override
    public void startOrStop(Integer status, Long id) {
        // TODO 起售套餐时，判断套餐内是否有停售菜品，有停售菜品提示"套餐内包含未启售菜品，无法启售"
        Setmeal setmeal = Setmeal.builder().id(id).status(status).updateTime(LocalDateTime.now()).updateUser(BaseContext.getCurrentId()).build();
        setmealMapper.updateById(setmeal);
    }

    /**
     * 条件查询
     *
     * @param setmeal
     * @return
     */
    @Override
    public List<Setmeal> list(Setmeal setmeal) {
        if (ObjectUtils.isEmpty(setmeal)) {
            return null;
        }
        // 1.条件构造器
        LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(ObjectUtils.isNotEmpty(setmeal.getName()), Setmeal::getName, setmeal.getName());
        queryWrapper.eq(ObjectUtils.isNotEmpty(setmeal.getCategoryId()), Setmeal::getCategoryId, setmeal.getCategoryId());
        queryWrapper.eq(ObjectUtils.isNotEmpty(setmeal.getStatus()), Setmeal::getStatus, setmeal.getStatus());
        queryWrapper.orderByDesc(Setmeal::getCreateTime);
        // 2.查询并返回数据
        List<Setmeal> list = setmealMapper.selectList(queryWrapper);
        return list;
    }

    /**
     * 根据id查询菜品选项
     *
     * @param id
     * @return
     */
    @Override
    public List<DishItemVO> getDishItemById(Long id) {
        return setmealMapper.getDishItemBySetmealId(id);
    }
}
